package com.ssyt.examinationsystem.controller;

import com.alibaba.fastjson.JSON;
import com.ssyt.examinationsystem.dto.PaperDto;
import com.ssyt.examinationsystem.entity.ManualEntity;
import com.ssyt.examinationsystem.entity.PaperInfo;
import com.ssyt.examinationsystem.entity.ScoreInfo;
import com.ssyt.examinationsystem.entity.StudentInfo;
import com.ssyt.examinationsystem.service.*;
import com.ssyt.examinationsystem.service.impl.*;
import com.ssyt.examinationsystem.util.CollectionUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Servlet implementation class CheckSubjectiveController
 */
public class CheckSubjectiveController extends HttpServlet {
    private static final long serialVersionUID = 1L;

    private ArrayList<Map<String, Object>> reCheckList = new ArrayList<Map<String, Object>>();

    /**
     * @see HttpServlet#HttpServlet()
     */
    public CheckSubjectiveController() {
        super();
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     * response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
     * response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取flag值
        String flag = request.getParameter("flag");

        // 创建安排考试业务对象
        IPaperInfoService paperService = new PaperInfoServiceImpl();
        ISubjectiveInfoService subjectiveService = new SubjectiveInfoServiceImpl();
        IScoreInfoService ScoreService = new ScoreInfoServiceImpl();
        // 主观答题信息业务对象
        ISubAnswerInfoService subAnswerService = new SubAnswerInfoServiceImpl();

        IStudentInfoService stuService = new StudentInfoServiceImpl();

        //
        PrintWriter out = response.getWriter();

        if ("query".equals(flag)) {
            query(request, response);
        } else if ("list".equals(flag)) {
            list(stuService, paperService, subAnswerService, request, response, out);
        } else if ("initCheck".equals(flag)) {
            initCheck(paperService, subAnswerService, request, response, out, subjectiveService);
        } else if ("check".equals(flag)) {
            check(subAnswerService, ScoreService, request, response, out);
        } else if ("initReCheck".equals(flag)) {
            initReCheck(request, response);
        } else if ("relist".equals(flag)) {
            relist(stuService, paperService, subAnswerService, request, response, out);
        } else if ("inReCheck".equals(flag)) {
            inReCheck(paperService, subAnswerService, request, response, out, subjectiveService);
        }

        out.flush();
        out.close();
    }

    /**
     * 重新阅卷
     *
     * @param scoreService
     * @param request
     * @param response
     * @param out
     * @throws IOException
     * @throws ServletException
     */
    private void inReCheck(IPaperInfoService paperService, ISubAnswerInfoService subAnswerService,
                           HttpServletRequest request, HttpServletResponse response, PrintWriter out,
                           ISubjectiveInfoService subjectiveService) throws ServletException, IOException {
        String subId = request.getParameter("subId");
        // 调用根据编号查询主观答题信息对象
        Map<String, Object> subAnswer = subAnswerService.getSubAnswerBySubId(subId);
        // 获取学生答案
        String stuAnswer = String.valueOf(subAnswer.get("answer"));
        // 获取主观题号
        String ids = String.valueOf(subAnswer.get("ids"));
        String paperId = String.valueOf(subAnswer.get("paperId"));
        String stuId = String.valueOf(subAnswer.get("stuId"));

        PaperDto paperDto = paperService.getPaperInfoById(paperId);
        String testId = String.valueOf(paperDto.getPaper().get("testId"));
        // 通过规则编号获取规则信息
        Map<String, Object> rule = paperDto.getRule();
        // 存放每题分数的集合
        List<Float> subScore = new ArrayList<Float>();

        if ("1".equals(testId)) {
            String subIds = String.valueOf(rule.get("subIds"));

            List<ManualEntity> manualList = JSON.parseArray(subIds, ManualEntity.class);

            for (int i = 0; i < manualList.size(); i++) {
                subScore.add(Float.valueOf(manualList.get(i).getScore()));
            }

        } else {
            // 获取主观题个数
            Integer subNumber = Integer.valueOf(String.valueOf(rule.get("subNumber")));
            for (int i = 0; i < subNumber; i++) {
                float score = Float.valueOf(String.valueOf(rule.get("subScore"))) / subNumber;
                subScore.add(score);
            }
        }

        // 得到所有学生答案数组
        String[] answerArray = stuAnswer.split("-");
        // 得到所有主观题编号数组
        String[] idsArray = ids.split("-");

        String[] subAnswerScore = null;
        if (CollectionUtils.isEmptyForList(reCheckList)) {
            for (Map<String, Object> map : reCheckList) {
                if (stuId.equals(String.valueOf(map.get("stuId")))
                        && paperId.equals(String.valueOf(map.get("paperId")))) {
                    subAnswerScore = (String[]) map.get("subScore");
                }
            }
        }

        // 创建一个存放批改页面所需内容的集合
        List<Map<String, Object>> subAnswerList = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < idsArray.length; i++) {
            // 新建一个Map集合，存放每题信息
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("stuAnswer", answerArray[i]);
            Map<String, Object> sub = subjectiveService.getSubById(idsArray[i]);
            // 获取题干
            String question = String.valueOf(sub.get("question"));
            // 获取参考答案
            String answer = String.valueOf(sub.get("answer"));

            map.put("subScore", subAnswerScore[i]);
            map.put("question", question);
            map.put("answer", answer);
            map.put("score", subScore.get(i));

            subAnswerList.add(map);
        }
        // 将批改页面内容集合存放在请求对象中
        request.setAttribute("subAnswerList", subAnswerList);
        request.setAttribute("stuId", stuId);
        request.setAttribute("paperId", paperId);

        request.getRequestDispatcher("WEB-INF/views/check/reCheck.jsp").forward(request, response);
    }

    /**
     * 重新阅卷列表
     *
     * @param subAnswerService
     * @param request
     * @param response
     * @param out
     */
    private void relist(IStudentInfoService stuService, IPaperInfoService paperService,
                        ISubAnswerInfoService subAnswerService, HttpServletRequest request, HttpServletResponse response,
                        PrintWriter out) {
        String subIds = "";
        if (CollectionUtils.isEmptyForList(reCheckList)) {
            for (Map<String, Object> map : reCheckList) {
                subIds = subIds + String.valueOf(map.get("subId")) + ",";
            }

            subIds = subIds.substring(0, subIds.length() - 1);

            // 获取重新阅卷的列表
            List<Map<String, Object>> checkList = subAnswerService.getReCheckList(subIds);
            if (CollectionUtils.isEmptyForList(checkList) && CollectionUtils.isEmptyForList(reCheckList)) {
                for (int i = 0; i < checkList.size(); i++) {
                    String[] subScore = (String[]) reCheckList.get(i).get("subScore");
                    checkList.get(i).put("subScore", subScore);
                }
            }

            if (CollectionUtils.isEmptyForList(checkList)) {
                for (Map<String, Object> map : checkList) {
                    String stuId = String.valueOf(map.get("stuId"));
                    String paperId = String.valueOf(map.get("paperId"));

                    Map<String, Object> stu = stuService.getStuByStuId(stuId);
                    String stuName = String.valueOf(stu.get("stuName"));
                    map.put("stuName", stuName);

                    String paperName = paperService.getPaperName(paperId);
                    map.put("paperName", paperName);
                }
            }

            String reCheckJson = JSON.toJSONString(checkList, true);
            out.print(reCheckJson);
        }
    }

    /**
     * 初始化重新阅卷页面
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     */
    private void initReCheck(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.getRequestDispatcher("WEB-INF/views/check/reSubAnswerList.jsp").forward(request, response);
    }

    /**
     * 提交批改的主观题成绩
     *
     * @param scoreService
     * @param request
     * @param response
     * @param out
     */
    private void check(ISubAnswerInfoService subAnswerService, IScoreInfoService scoreService,
                       HttpServletRequest request, HttpServletResponse response, PrintWriter out) {
        // 获取试卷和学生编号
        String paperId = request.getParameter("paperId");
        String stuId = request.getParameter("stuId");
        // 计算主观题分数
        float subjectiveScore = 0;
        String[] subScore = request.getParameterValues("subScore");
        for (int i = 0; i < subScore.length; i++) {
            subjectiveScore += Float.valueOf(subScore[i]);
        }
        // 创建成绩对象，并封装属性
        ScoreInfo scoreInfo = new ScoreInfo();
        scoreInfo.setSubjectiveScore(subjectiveScore);

        PaperInfo paper = new PaperInfo();
        paper.setPaperId(Integer.valueOf(paperId));
        scoreInfo.setPaper(paper);

        StudentInfo stu = new StudentInfo();
        stu.setStuId(Integer.valueOf(stuId));
        scoreInfo.setStu(stu);
        // 调用根据试卷和学生编号查询主观答题编号
        String subId = subAnswerService.getSubAnswerByPaperIdAndStuId(paperId, stuId);
        // 调用修改主观成绩的业务方法
        if (scoreService.updateScoreByPaperIdAndStuId(scoreInfo) > 0) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("subId", subId);
            map.put("paperId", paperId);
            map.put("stuId", stuId);
            map.put("subScore", subScore);
            reCheckList.add(map);

            out.print("ok");
        }
    }

    /**
     * 初始化批改页面
     *
     * @param subAnswerService
     * @param request
     * @param response
     * @param out
     * @throws IOException
     * @throws ServletException
     */
    private void initCheck(IPaperInfoService paperService, ISubAnswerInfoService subAnswerService,
                           HttpServletRequest request, HttpServletResponse response, PrintWriter out,
                           ISubjectiveInfoService subjectiveService) throws ServletException, IOException {
        String subId = request.getParameter("subId");
        // 调用根据编号查询主观答题信息对象
        Map<String, Object> subAnswer = subAnswerService.getSubAnswerBySubId(subId);
        // 获取学生答案
        String stuAnswer = String.valueOf(subAnswer.get("answer"));
        // 获取主观题号
        String ids = String.valueOf(subAnswer.get("ids"));
        String paperId = String.valueOf(subAnswer.get("paperId"));
        String stuId = String.valueOf(subAnswer.get("stuId"));

        PaperDto paperDto = paperService.getPaperInfoById(paperId);
        String testId = String.valueOf(paperDto.getPaper().get("testId"));
        // 通过规则编号获取规则信息
        Map<String, Object> rule = paperDto.getRule();
        // 存放每题分数的集合
        List<Float> subScore = new ArrayList<Float>();

        if ("1".equals(testId)) {
            String subIds = String.valueOf(rule.get("subIds"));

            List<ManualEntity> manualList = JSON.parseArray(subIds, ManualEntity.class);

            for (int i = 0; i < manualList.size(); i++) {
                subScore.add(Float.valueOf(manualList.get(i).getScore()));
            }

        } else {
            // 获取主观题个数
            Integer subNumber = Integer.valueOf(String.valueOf(rule.get("subNumber")));
            for (int i = 0; i < subNumber; i++) {
                float score = Float.valueOf(String.valueOf(rule.get("subScore"))) / subNumber;
                subScore.add(score);
            }
        }

        // 得到所有学生答案数组
        String[] answerArray = stuAnswer.split("-");
        // 得到所有主观题编号数组
        String[] idsArray = ids.split("-");
        // 创建一个存放批改页面所需内容的集合
        List<Map<String, Object>> subAnswerList = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < idsArray.length; i++) {
            // 新建一个Map集合，存放每题信息
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("stuAnswer", answerArray[i]);
            Map<String, Object> sub = subjectiveService.getSubById(idsArray[i]);
            // 获取题干
            String question = String.valueOf(sub.get("question"));
            // 获取参考答案
            String answer = String.valueOf(sub.get("answer"));

            map.put("question", question);
            map.put("answer", answer);
            map.put("score", subScore.get(i));

            subAnswerList.add(map);
        }
        // 将批改页面内容集合存放在请求对象中
        request.setAttribute("subAnswerList", subAnswerList);
        request.setAttribute("stuId", stuId);
        request.setAttribute("paperId", paperId);
        request.getRequestDispatcher("WEB-INF/views/check/checkSubjective.jsp").forward(request, response);

    }

    /**
     * 显示所有主观答题信息
     *
     * @param subAnswerService
     * @param request
     * @param response
     */
    private void list(IStudentInfoService stuService, IPaperInfoService paperService,
                      ISubAnswerInfoService subAnswerService, HttpServletRequest request, HttpServletResponse response,
                      PrintWriter out) {

        // 调用查询所有主观答题信息的方法
        List<Map<String, Object>> subAnswerList = subAnswerService.getSubAnswer();

        if (CollectionUtils.isEmptyForList(subAnswerList)) {
            for (Map<String, Object> map : subAnswerList) {
                String stuId = String.valueOf(map.get("stuId"));
                String paperId = String.valueOf(map.get("paperId"));

                Map<String, Object> stu = stuService.getStuByStuId(stuId);
                String stuName = String.valueOf(stu.get("stuName"));
                map.put("stuName", stuName);

                String paperName = paperService.getPaperName(paperId);
                map.put("paperName", paperName);
            }
        }

        String subAnswer = JSON.toJSONString(subAnswerList, true);
        out.print(subAnswer);

    }

    /**
     * 转发到主观答题信息显示页面
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     */
    private void query(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getRequestDispatcher("WEB-INF/views/check/subAnswerList.jsp").forward(request, response);
    }

}
